package xhwl.hmo.mall.db;


import android.content.Context;
import android.util.Log;

import com.lidroid.xutils.DbUtils;
import com.lidroid.xutils.exception.DbException;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;

/**
* 数据库操作基类，定义创建数据库、创建表、表操作
* @author lim
* @date 2017年2月9日
* @version 1.0
* @param <T> 表对象
*/
public abstract class BaseDao<T> {
    protected static final String TAG = "BaseDao";
	public DbUtils db;
    private Class<T> clazz;
    /**
     * @param context
     * @param Dbname 数据库名称
     * @param dbVersion 数据库版本号
     */ 
    @SuppressWarnings("unchecked")
    public BaseDao(Context context, String Dbname, int dbVersion) {
        db = createDb(context,Dbname,dbVersion);
        Type genType = this.getClass().getGenericSuperclass();
        Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
        this.clazz = (Class<T>) params[0];
        try {
            createTable();
        } catch (DbException e) {
            e.printStackTrace();
        }
    }

    /**
    * 创建数据库
    * @param context
    * @param dbName 数据库名称
    * @param dbVersion 数据库版本号
    * @return 数据库操作对象 
    */ 
    private DbUtils createDb(Context context, final String dbName, int dbVersion) {
        DbUtils db = DbUtils.create(context, dbName, dbVersion, new DbUtils.DbUpgradeListener() {
            @Override
            public void onUpgrade(DbUtils db, int oldVersion, int newVersion) {
                //base on dbname,compare dbversions,then update db tables
                Log.e(TAG,"dbName="+dbName+" oldVersion="+oldVersion+" newVersion="+newVersion);
                onUpgrade(db,oldVersion,newVersion);
            }
        });
        return db;
    }
    /**
    * 子类需要复写方法、数据库升级是对表的操作
    * @param db
    * @param oldVersion
    * @param newVersion
    */ 
    public abstract void onUpgrade(DbUtils db, int oldVersion, int newVersion);
    
    /**
    * 创建表
    * @throws DbException
    */ 
    private void createTable() throws DbException {
        db.createTableIfNotExist(clazz);
    }

    /**
     * 保存一组对象
     * @param list
     * @throws DbException
     */
    public void save(List<T> list)  throws DbException {
        if (list != null) {
			for (T t : list) {
			    db.save(t);
			}
        }
    }
    /**
     * 保存单个对象
     * @param t
     * @throws DbException
     */
    public void save(T t)  throws DbException {
        if (t != null) {
			db.save(t);
        }
    }
    
    /**
     * 保存一组对象、给对象id赋值
     * @param t
     * @throws DbException
     */ 
    public void saveBindingId(List<T> list)  throws DbException {
    	if (list != null) {
			for (T t : list) {
			    db.saveBindingId(t);
			}
        }
    }
    /**
     * 保存对象、给对象id赋值
     * @param t
     * @throws DbException
     */ 
     public void saveBindingId(T t)  throws DbException {
     	if (t != null) {
 			db.saveBindingId(t);
         }
     }
    /**
     * 根据id查找对象
     * @param id
     * @return
     * @throws DbException
     */
    public T findById(int id) throws DbException {
        T entity = (T) db.findById(clazz, id);
        return entity;
    }
    
    /**
    * 查找所有对象
    * @return
    * @throws DbException
    */ 
    public List<T> findAll() throws DbException {
        List<T> list = new ArrayList<T>();
        if (db != null) {
            list = (List<T>) db.findAll(clazz);
        }
        return list;
    }

    /**
     * 自定义查找
     * @param sql 查询条件、内容自定义（如：查询条件，拼接字符串、json等）
     * @return
     * @throws DbException
     */
    public abstract T find(String sql) throws DbException;

    /**
     * 更新指定id对象
     * @param t
     * @return
     */
    public void update(T t)  throws DbException {
		db.update(t);
    };
    /**
     * 根据id查找，saveOrUpdate
     * @param t
     */
    public void saveOrUpdate(T t)  throws DbException {
		db.saveOrUpdate(t);
    };
    /**
     * 根据id进行删除
     * @param id
     * @throws DbException
     */
    public void deleteById(int id)  throws DbException {
		db.deleteById(clazz, id);
    }

    /**
     * 删除对象
     * @param t
     * @throws DbException
     */
    public void delete(T t) throws DbException {
		db.delete(t);
    }

}
